﻿#include "Etat.h"
#include "Transition.h"
#include "Etiquette.h"
#include "ListeEtats.h"

#include <string>
#include <iostream>
#include <map>

using std::string;
using std::cout;
using std::endl;
using std::map;

typedef vector<Transition*>::iterator transIterator;

Etat::Etat()
{
	id = 0;
	initial = false;
	terminal = false;
}

Etat::Etat(unsigned id, bool initial, bool terminal)
: id(id), initial(initial), terminal(terminal)
{

}

Etat::~Etat()
{

}

bool Etat::existeTrans(char c)
{
	//Pour toutes les transitions
	for (unsigned i = 0; i < transitions.size(); ++i)
	{
		if (transitions[i]->getEtiquette().contientSymbole(c))
			return true;
	}
	return false;
}

ListeEtats Etat::cible(char c)
{
	ListeEtats liste;

	//Pour toutes les transitions
	for (unsigned i = 0; i < transitions.size(); ++i)
	{
		if (transitions[i]->getEtiquette().contientSymbole(c))
			liste.addEtat(transitions[i]->getDestination());
	}

	return liste;
}

ListeEtats Etat::cible()
{
	ListeEtats liste;

	//Pour toutes les transitions
	for (unsigned i = 0; i < transitions.size(); ++i)
		liste.addEtat(transitions[i]->getDestination());

	return liste;
}

void Etat::ajouterTransition(Etiquette c, Etat* e)
{
	//Si la transition existe deja, mais qu'on veut ajouter des symboles...
	for (transIterator it = transitions.begin(); it != transitions.end(); ++it)
	{
		if ((*it)->getDestination() == e)
		{
			(*it)->addSymboles(c.getSymboles());
			return;
		}
	}

	//Sinon
	Transition* transition = new Transition(c, this, e);
	transitions.push_back(transition);
}

unsigned Etat::getId() const
{
	return id;
}

void Etat::print()
{
	cout << "Etat: " << this->id << endl;
	cout << "Transitions: " << endl;
	for (unsigned i = 0; i < transitions.size(); ++i)
	{
		cout << "\t Lien #" << i+1 << "{ Symbole(s): ";
		cout << transitions[i]->getEtiquette().getSymboles();
		cout << "; Destination: " << transitions[i]->getDestination()->getId() << "}" << endl;
	}
	

}

bool Etat::estInitial() const
{
	return initial;
}

bool Etat::estTerminal() const
{
	return terminal;
}

bool Etat::operator==(Etat& etat) const
{
	return this->id == etat.id;
}

void Etat::retirerTransition(unsigned id)
{
	for (transIterator it = transitions.begin(); it != transitions.end(); ++it)
	{
		if ((*it)->getDestination()->getId() == id)
		{
			it = transitions.erase(it);
			break;
		}
	}
}

const ListeTransitions& Etat::getTransitions() const
{
	return transitions;
}

Etiquette Etat::listerEtiquettes()
{
	map<char, bool> charTrouve;
	Etiquette etiquetteFinale;
	for (transIterator it = transitions.begin(); it != transitions.end(); ++it)
	{
		const Etiquette& etiquette = (*it)->getEtiquette();
		string symboles = etiquette.getSymboles();
		for (string::iterator it2 = symboles.begin(); it2 != symboles.end(); ++it2)
		{
			char charCourrant = *it2;
			if (charTrouve[charCourrant] == false)
			{
				etiquetteFinale.addSymbole(charCourrant);
				charTrouve[charCourrant] = true;
			}
		}
	}
	return etiquetteFinale;
}
